package j3d.samples;

import java.applet.Applet;

import java.awt.*;

import java.awt.event.*;

import com.sun.j3d.utils.applet.MainFrame;

import com.sun.j3d.utils.universe.*;

import javax.media.j3d.*;

import javax.vecmath.*;

import com.sun.j3d.utils.geometry.Sphere;

import javax.swing.Timer;

public class BouncingBall extends Applet implements ActionListener, KeyListener {

    private Button go = new Button("Go");

    private TransformGroup objTrans;

    private Transform3D trans = new Transform3D();

    private float height = 0.0f;

    private float sign = 1.0f; // going up or down

    private Timer timer;

    private float xloc = 0.0f;
    private final SimpleUniverse simpleUniverse;
    private BranchGroup sceneGraph;
    private BranchGroup objRoot = new BranchGroup();

    public BranchGroup createSceneGraph(float size) {

        objRoot = new BranchGroup();

        // Create the root of the branch graph

        objTrans = new TransformGroup();

        objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

        objRoot.addChild(objTrans);

        // Create a simple shape leaf node, add it to the scene graph.

        Sphere sphere = new Sphere(size);

        objTrans = new TransformGroup();

        objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

        Transform3D pos1 = new Transform3D();

        pos1.setTranslation(new Vector3f(0.0f, 0.0f, 0.0f));

        objTrans.setTransform(pos1);

        objTrans.addChild(sphere);

        objRoot.addChild(objTrans);

        BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);

        Color3f light1Color = new Color3f(1.0f, 0.0f, 0.2f);

        Vector3f light1Direction = new Vector3f(4.0f, -7.0f, -12.0f);

        DirectionalLight light1 = new DirectionalLight(light1Color, light1Direction);

        light1.setInfluencingBounds(bounds);

        objRoot.addChild(light1);

        // Set up the ambient light

        Color3f ambientColor = new Color3f(1.0f, 1.0f, 1.0f);

        AmbientLight ambientLightNode = new AmbientLight(ambientColor);

        ambientLightNode.setInfluencingBounds(bounds);

        objRoot.addChild(ambientLightNode);

        return objRoot;

    }

    public BouncingBall() {

        setLayout(new BorderLayout());

        GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();

        Canvas3D c = new Canvas3D(config);

        add("Center", c);

        c.addKeyListener(this);

        timer = new Timer(100, this);

        //timer.start();

        Panel p = new Panel();

        p.add(go);

        add("North", p);

        go.addActionListener(this);

        go.addKeyListener(this);

        // Create a simple scene and attach it to the virtual universe

        //BranchGroup scene = ;

        simpleUniverse = new SimpleUniverse(c);

        simpleUniverse.getViewingPlatform().setNominalViewingTransform();

        sceneGraph = createSceneGraph(0.25f);

        sceneGraph.setCapability(BranchGroup.ALLOW_DETACH);

        simpleUniverse.addBranchGraph(sceneGraph);

        objRoot = new BranchGroup();
    }

    public void keyPressed(KeyEvent e) {

        //Invoked when a key has been pressed.

        if (e.getKeyChar() == 's') {
            xloc = xloc + .1f;
        }

        if (e.getKeyChar() == 'a') {
            xloc = xloc - .1f;
        }

    }

    public void keyReleased(KeyEvent e) {

        // Invoked when a key has been released.

    }

    public void keyTyped(KeyEvent e) {

        //Invoked when a key has been typed.

    }

    public void actionPerformed(ActionEvent e) {

        // start timer when button is pressed

        if (e.getSource() == go) {

            if (!timer.isRunning()) {

                timer.start();

            }

        } else {

            height += .1 * sign;

            if (Math.abs(height * 2) >= 1) sign = -1.0f * sign;

            if (height < -0.4f) {

                trans.setScale(new Vector3d(1.0, .8, 1.0));

            } else {

                trans.setScale(new Vector3d(1.0, 1.0, 1.0));

            }


            sceneGraph.detach();

            sceneGraph = createSceneGraph(height);

            sceneGraph.setCapability(BranchGroup.ALLOW_DETACH);

            sceneGraph.compile();

            simpleUniverse.addBranchGraph(sceneGraph);

            //trans.setTranslation(new Vector3f(xloc, height, 0.0f));

            //objTrans.setTransform(trans);

        }

    }

    public static void main(String[] args) {

        System.out.println("Program Started");

        BouncingBall bb = new BouncingBall();

        bb.addKeyListener(bb);

        MainFrame mf = new MainFrame(bb, 256, 256);

    }

}

